home *** CD-ROM | disk | FTP | other *** search
- /* clip.c */
- /* written by Jason R. Wilson 2/21/93 */
- /* this package provides a 3-D clip routine */
-
- #include <math.h>
- #include <stdio.h>
- #include "datastruct.h"
-
- /***********************************************************************/
-
-
- Boolean inside (VisVertexCell *A,int Case,double bound)
-
- {
- Boolean temp;
- temp = false;
-
- switch (Case) {
- case 1: if (A->ViewPosition.hom[3] >= bound) temp = true;
- break;
- case 2: if (A->ViewPosition.hom[0] <= bound) temp = true;
- break;
- case 3: if (A->ViewPosition.hom[1] <= bound) temp = true;
- break;
- case 4: if (A->ViewPosition.hom[0] >= bound) temp = true;
- break;
- case 5: if (A->ViewPosition.hom[1] >= bound) temp = true;
- break;
- }
- return temp;
- }
- /***********************************************************************/
-
- Boolean outside (VisVertexCell *A,int Case,double bound)
-
- {
- if (inside (A,Case,bound) == true)
- return false;
- else
- return true;
- }
-
- /***********************************************************************/
-
-
- void ClipTo (VisVertexCell *OldVerts,PolygonCell *Poly,Boolean *Gone,
- int Case,double bound)
-
- /* Clips against one plane */
-
- {
- VisVertexCell *New;
- VisVertexCell *NewB;
- VisVertexCell *A;
- VisVertexCell *B;
- VisVertexCell *Traverse;
- Boolean Output;
- Boolean Intersect;
- double t;
- VisVertexCell *traverse,*tempfree;
-
- Traverse = OldVerts;
-
- Poly->VisVertices = NULL;
-
- while (!(Traverse == NULL))
- {
- A = Traverse; /* set up A */
-
- if (Traverse->Next == NULL) /* set up B */
- B = OldVerts;
- else
- B = Traverse->Next;
-
- Intersect = false;
-
-
- if (inside (A,Case,bound) && inside (B,Case,bound))
- Output = true;
- else
- if (outside (A,Case,bound) && outside (B,Case,bound))
- Output = false;
- else
- {
- switch (Case) {
- case 1:
- t = (bound - A->ViewPosition.hom[3])/
- (B->ViewPosition.hom[3] - A->ViewPosition.hom[3]);
- break;
- case 2:
- t = (bound - A->ViewPosition.hom[0])/
- (B->ViewPosition.hom[0] - A->ViewPosition.hom[0]);
- break;
- case 3:
- t = (bound - A->ViewPosition.hom[1])/
- (B->ViewPosition.hom[1] - A->ViewPosition.hom[1]);
- break;
- case 4:
- t = (bound - A->ViewPosition.hom[0])/
- (B->ViewPosition.hom[0] - A->ViewPosition.hom[0]);
- break;
- case 5:
- t = (bound - A->ViewPosition.hom[1])/
- (B->ViewPosition.hom[1] - A->ViewPosition.hom[1]);
- break;
- }
- Intersect = true;
- New = (VisVertexCell *)
- (malloc (sizeof (VisVertexCell))); /* allocate for new*/
- InitVisVertexCell (New);
- New->ViewPosition.hom[0] = A->ViewPosition.hom[0] +
- (B->ViewPosition.hom[0] - A->ViewPosition.hom[0])*t;
- New->ViewPosition.hom[1] = A->ViewPosition.hom[1] +
- (B->ViewPosition.hom[1] - A->ViewPosition.hom[1])*t;
- New->ViewPosition.hom[2] = A->ViewPosition.hom[2] +
- (B->ViewPosition.hom[2] - A->ViewPosition.hom[2])*t;
- New->ViewPosition.hom[3] = A->ViewPosition.hom[3] +
- (B->ViewPosition.hom[3] - A->ViewPosition.hom[3])*t;
- New->B.r = A->B.r + (B->B.r - A->B.r)*t;
- New->B.g = A->B.g + (B->B.g - A->B.g)*t;
- New->B.b = A->B.b + (B->B.b - A->B.b)*t;
-
- /* compute the new intensity value for the new point */
- if (outside (A,Case,bound))
- Output = true;
- else Output = false;
- }
- if (Intersect == true)
- {
- New->Next = Poly->VisVertices;
- Poly->VisVertices = New;
- }
- if (Output == true)
- {
- NewB = (VisVertexCell *)(malloc(sizeof (VisVertexCell)));
- InitVisVertexCell (NewB);
- NewB->ViewPosition.hom[0] = B->ViewPosition.hom[0];
- NewB->ViewPosition.hom[1] = B->ViewPosition.hom[1];
- NewB->ViewPosition.hom[2] = B->ViewPosition.hom[2];
- NewB->ViewPosition.hom[3] = B->ViewPosition.hom[3];
- NewB->B.r = B->B.r;
- NewB->B.g = B->B.g;
- NewB->B.b = B->B.b;
- NewB->Next = Poly->VisVertices;
- Poly->VisVertices = NewB;
- }
-
- Traverse = Traverse->Next;
- }
-
-
- /* free up memory */
- traverse = OldVerts;
- while (!(traverse == NULL))
- {
- tempfree = traverse;
- traverse = traverse->Next;
- free (tempfree);
- }
-
-
- if (Poly->VisVertices == NULL) /* is any of the polygon left */
- *Gone = true;
- else *Gone = false;
-
- }
-
-
-
- /***********************************************************************/
-
-
-
- void ClipPolygon (PolygonCell *Poly,Window ViewWindow,
- Boolean *Gone)
-
- /* clips to Wtol */
- /* does perspective divisions */
- /* clips a polygon to the view volume defined by Wl, Wr, Wt, and Wb */
- /* returns the new list of vertices */
-
- {
- VertexListCell *traverselist;
- VisVertexCell *newvertex;
- VisVertexCell *traverse,*tempfree;
-
-
- /* free up memory */
- traverse = Poly->VisVertices;
-
- while (!(traverse == NULL))
- {
- tempfree = traverse;
- traverse = traverse->Next;
- free (tempfree);
- }
-
- Poly->VisVertices = NULL;
-
-
- traverselist = Poly->Vertices;
-
- while (!(traverselist == NULL))
-
- {
- newvertex = (VisVertexCell *)(malloc (sizeof(VisVertexCell)));
- InitVisVertexCell (newvertex);
- newvertex->ViewPosition = traverselist->Vertex->ViewPosition;
- newvertex->B.r = traverselist->Vertex->B.r;
- newvertex->B.g = traverselist->Vertex->B.g;
- newvertex->B.b = traverselist->Vertex->B.b;
- newvertex->Next = Poly->VisVertices;
- Poly->VisVertices = newvertex;
- traverselist = traverselist->Rest;
- }
-
-
- ClipTo (Poly->VisVertices,Poly,Gone,1,Wtol);
-
- /* do the perspective divisions */
-
- traverse = Poly->VisVertices;
-
-
- while (!(traverse == NULL))
- {
- traverse->ViewPosition.hom[0] =
- traverse->ViewPosition.hom[0]/traverse->ViewPosition.hom[3];
- traverse->ViewPosition.hom[1] =
- traverse->ViewPosition.hom[1]/traverse->ViewPosition.hom[3];
- traverse->ViewPosition.hom[2] =
- traverse->ViewPosition.hom[2]/traverse->ViewPosition.hom[3];
- traverse = traverse->Next;
- }
-
-
- if (!(*Gone == true))
- ClipTo (Poly->VisVertices,
- Poly,Gone,2,ViewWindow.Wr);
-
- if (!(*Gone == true))
- ClipTo (Poly->VisVertices,
- Poly,Gone,3,ViewWindow.Wt);
-
- if (!(*Gone == true))
- ClipTo (Poly->VisVertices,
- Poly,Gone,4,ViewWindow.Wl);
-
- if (!(*Gone == true))
- ClipTo (Poly->VisVertices,
- Poly,Gone,5,ViewWindow.Wb);
-
-
- }
-
-
-
-